import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.Objects;

/**
 * 加减法口算练习系统-v0.3
 * 新增功能：
 * 1. 生成无重复算式（基于操作数和运算符判断）
 * 2. 控制加减比例（默认25道加法+25道减法）
 */
public class CalculationSystemV03 {
    // 常量配置
    private static final int TOTAL_QUESTIONS = 50;
    private static final int MAX_NUMBER = 99;
    private static final int QUESTIONS_PER_LINE = 5;
    private static final int ADD_COUNT = 25; // 加法题数
    private static final int SUB_COUNT = 25; // 减法题数

    /**
     * 内部类：封装算式，重写equals和hashCode实现去重
     */
    private static class Exercise {
        int num1;
        int num2;
        char operator;
        int answer;

        public Exercise(int num1, int num2, char operator, int answer) {
            this.num1 = num1;
            this.num2 = num2;
            this.operator = operator;
            this.answer = answer;
        }

        @Override
        public String toString() {
            return String.format("%d %c %d = %d", num1, operator, num2, answer);
        }

        // 重写equals：判断两个算式是否相同（操作数和运算符一致）
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Exercise exercise = (Exercise) o;
            return num1 == exercise.num1 && num2 == exercise.num2 && operator == exercise.operator;
        }

        // 重写hashCode：配合Set去重
        @Override
        public int hashCode() {
            return Objects.hash(num1, num2, operator);
        }
    }

    public static void main(String[] args) {
        System.out.println("加减法口算练习系统-v0.3");
        System.out.println("=".repeat(50));
        System.out.printf("共%d道题（加法%d道+减法%d道，无重复）\n", TOTAL_QUESTIONS, ADD_COUNT, SUB_COUNT);
        System.out.println("=".repeat(50));

        // 生成无重复、按比例的算式
        List<Exercise> exercises = generateExercises();

        // 输出算式
        printExercises(exercises);

        // 验证算式正确性（可选，用于测试）
        validateExercises(exercises);
    }

    /**
     * 生成无重复、按比例的算式
     * @return 算式列表
     */
    private static List<Exercise> generateExercises() {
        List<Exercise> exercises = new ArrayList<>(TOTAL_QUESTIONS);
        Set<Exercise> uniqueExercises = new HashSet<>(); // 用于去重
        Random random = new Random();

        // 1. 生成指定数量的加法算式（无重复）
        int addGenerated = 0;
        while (addGenerated < ADD_COUNT) {
            int num1 = random.nextInt(MAX_NUMBER + 1);
            int num2 = random.nextInt(MAX_NUMBER + 1);
            char operator = '+';
            int answer = num1 + num2;

            if (answer > 100) continue; // 加法约束

            Exercise exercise = new Exercise(num1, num2, operator, answer);
            if (!uniqueExercises.contains(exercise)) { // 无重复则添加
                uniqueExercises.add(exercise);
                exercises.add(exercise);
                addGenerated++;
            }
        }

        // 2. 生成指定数量的减法算式（无重复）
        int subGenerated = 0;
        while (subGenerated < SUB_COUNT) {
            int num1 = random.nextInt(MAX_NUMBER + 1);
            int num2 = random.nextInt(MAX_NUMBER + 1);
            char operator = '-';

            if (num1 < num2) continue; // 减法约束

            int answer = num1 - num2;
            Exercise exercise = new Exercise(num1, num2, operator, answer);
            if (!uniqueExercises.contains(exercise)) { // 无重复则添加
                uniqueExercises.add(exercise);
                exercises.add(exercise);
                subGenerated++;
            }
        }

        return exercises;
    }

    /**
     * 格式化输出算式（与V0.2复用）
     * @param exercises 算式列表
     */
    private static void printExercises(List<Exercise> exercises) {
        for (int i = 0; i < exercises.size(); i++) {
            System.out.printf("%s\t", exercises.get(i));
            if ((i + 1) % QUESTIONS_PER_LINE == 0) {
                System.out.println();
            }
        }
        if (exercises.size() % QUESTIONS_PER_LINE != 0) {
            System.out.println();
        }
    }

    /**
     * 验证算式：检查数量、比例和唯一性（测试用）
     * @param exercises 算式列表
     */
    private static void validateExercises(List<Exercise> exercises) {
        // 统计加减题数
        int addCount = 0, subCount = 0;
        for (Exercise ex : exercises) {
            if (ex.operator == '+') addCount++;
            else subCount++;
        }

        // 检查唯一性（Set大小 == 总题数）
        boolean isUnique = new HashSet<>(exercises).size() == TOTAL_QUESTIONS;

        // 输出验证结果
        System.out.println("\n" + "=".repeat(50));
        System.out.println("验证结果：");
        System.out.printf("加法题数：%d（预期：%d）\n", addCount, ADD_COUNT);
        System.out.printf("减法题数：%d（预期：%d）\n", subCount, SUB_COUNT);
        System.out.printf("总题数：%d（预期：%d）\n", exercises.size(), TOTAL_QUESTIONS);
        System.out.printf("是否无重复：%s\n", isUnique ? "是" : "否");
        System.out.println("验证通过：" + (addCount == ADD_COUNT && subCount == SUB_COUNT && isUnique ? "是" : "否"));
    }
}
